import { _decorator, Node, UITransform, Vec2 } from 'cc'
import { EntityManager } from '../../Base/EntityManager'
import { IActor, InputTypeEnum, toFixed } from '../../Common'
import { EntityStateEnum, EventEnum } from '../../Enum'
import DataManager from '../../Global/DataManager'
import EventManager from '../../Global/EventManager'
import { WeaponStateMachine } from './WeaponStateMachine'
const { ccclass } = _decorator

@ccclass('WeaponManager')
export class WeaponManager extends EntityManager {
  private body: Node
  private anchor: Node
  private point: Node
  owner: number

  init(actor: IActor) {
    this.owner = actor.id
    this.body = this.node.getChildByName('Body')
    this.anchor = this.body.getChildByName('Anchor')
    this.point = this.anchor.getChildByName('Point')

    this.fsm = this.body.addComponent(WeaponStateMachine)
    this.fsm.init(actor.weaponType)
    this.state = EntityStateEnum.Idle

    EventManager.Instance.on(EventEnum.WeaponShoot, this.handleWeaponShoot, this)
    EventManager.Instance.on(EventEnum.BulletBorn, this.handleBulletBorn, this)
  }

  onDestroy() {
    EventManager.Instance.off(EventEnum.WeaponShoot, this.handleWeaponShoot, this)
    EventManager.Instance.off(EventEnum.BulletBorn, this.handleBulletBorn, this)
  }

  handleWeaponShoot() {
    if (this.owner !== DataManager.Instance.myPlayerId) return
    // 获取子弹发射点的世界坐标
    const pointWorldPos = this.point.getWorldPosition()
    // 计算发射点在舞台中的相对坐标,convertToNodeSpaceAR函数会将世界坐标转换为调用者的局部坐标
    const pointStagePos = DataManager.Instance.stage.getComponent(UITransform).convertToNodeSpaceAR(pointWorldPos)

    // 获取武器锚点的世界坐标
    const anchorWorldPos = this.anchor.getWorldPosition()
    // 计算子弹的朝向
    const direction = new Vec2(pointWorldPos.x - anchorWorldPos.x, pointWorldPos.y - anchorWorldPos.y).normalize()

    EventManager.Instance.emit(EventEnum.ClientSync, {
      type: InputTypeEnum.WeaponShoot,
      owner: this.owner,
      position: {
        x: toFixed(pointStagePos.x),
        y: toFixed(pointStagePos.y)
      },
      direction: {
        x: toFixed(direction.x),
        y: toFixed(direction.y)
      }
    })
  }

  handleBulletBorn(owner: number) {
    if (owner !== this.owner) return

    this.state = EntityStateEnum.Attack
  }
}
